#ifndef __READER_H__
#define __READER_H__

/// PACKET TYPES ///
#define COMMAND_FRAME 0xA5
#define RESPONSE_FRAME 0xE5
#define RESPONSE_FRAME_COMP 0xE9

/// COMMAND CODES ///
#define SET_PARAMETER 0x70 // Set single working parameters for reader.
#define GET_PARAMETER 0x71 // Read single working parameters for reader.
#define SET_MULTI_PARAMETER 0x72 // Set multi parameters or multi-byte parameters for reader/writer.
#define GET_MULTI_PARAMETER 0x73 // Read multi-parameters in EEPROM.
#define SET_BAUD_RATE 0x74 // Set Baud Rate for reader with RS232 interface.
#define RESET_READER 0x75 // Reset the command frame of Reader.
#define UPGRADE_START 0x76 // Starting upgrades the firmware for reader/writer.
#define UPGRADE_DATA 0x77 // Starting downloads the firmware.
#define UPGRADE_END 0x78 // End the firmware upgrading.
#define ID_MATCH_START 0x40 // Readers support ID match function. 
			// Before using this function, all the ID data should be written into reader 
			// and the entire operation should to be an atomic operation. It’s designed 
			// for 3 command packets which support ID match function.
#define ID_MATCH_DATA 0x41 // Starting writes the ID data to the reader which needs to match.
#define ID_MATCH_END 0x42 // End imputing the ID matching data.
#define UPGRADE_SELF_KILL 0x79 // Delete the firmware successful upgrading mark command frame.
#define GET_FIRMWARE_VERSION 0x7A //Reading the reader soft version command frame.
#define SET_WORK_ANTENNA 0x7B // Set the reader work antenna command frame.
#define SELECT_WORK_ANTENNA 0x69 // Set the reader work antenna command frame.
#define SET_ANTENNA_CYCLE 0x7C // Set the reader antenna cycle command frame.
#define ANTENNA_QUERY 0x6F // Check the antenna connected to reader.
#define SET_FRQ_HOPPING_MODE 0x7D // Set the reader hopping mode command frame.
#define SET_POWER 0x70 // Set reader’s RF power command frame.
#define ANTENNA_SWITCH 0x69 // Set the reader current work antenna command frame.

#define SINGLE_IDENTIFY 0x92 // Reader indentifying the single tag command frame.
#define SINGLE_IDENTIFY_EX 0xC1 // Identifying single tag under multi-antenna command frame.
#define MULTIPLE_IDENTIFY 0x93 // Multiple tags command frame.
#define MULTIPLE_IDENTIFY_EX 0xC2 // The reader identifies multiple tags under multi-antenna command frame.
#define GET_ID_BUF 0x61 // Reading ID data command frame.

/// BAUD RATES ///
#define BAUD9600 0x00
#define BAUD19200 0x01
#define BAUD38400 0x02
#define BAUD57600 0x03
#define BAUD115200 0x04

#define ARBITRARY_STATION 0xFF;
#define ISO_18000_6B 0x01
#define EPC_CLASS_1_GEN_2 0x04

#include <stdint.h>
#include "Comun.h"
#include "Serial.h"

typedef struct {
	uint32_t res;
	uint32_t id;
} PRODUCT_CODE;

class Reader : public Serial {
	public:
		Reader();
		~Reader();
		
		bool Connect( string device, BYTE br );
		bool Init();
		void SetTimeout( uint32_t tout ) { ReaderTimeout = tout; }
		bool SetBaudrate( BYTE br );
		bool GetFirmwareVersion( string& version );
		bool GetTagsNumber( uint8_t& number );
		PRODUCT_CODE *GetProductCode( uint8_t& count, PRODUCT_CODE *codes );
		
		bool Reset();
	
	private:
		size_t OnRequest( vector<BYTE> buffer );
		bool Receive( vector<BYTE>& buffer, uint32_t tout );
		
		BYTE Checksum( vector<BYTE> frame );
		bool Check( vector<BYTE> frame, BYTE command );
		
		pthread_mutex_t ReaderMtx;
		pthread_cond_t ReaderSgnl;
		
		vector<BYTE> Response;
		uint32_t ReaderTimeout, Readed;
		
};

#endif
